package log

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"github.com/satori/go.uuid"
	"os"
	"runtime"
	"strconv"
	"time"
)

// stdLogger 标准日志对象
var stdLogger = &Logger{}

// GetLogger 获取Logger
func GetLogger() *Logger {
	return stdLogger
}

// InitLogger 初始化Logger
func InitLogger(logDir, logName string, logSize int64) (err error) {
	stdLogger.Do(func() {
		err = stdLogger.init(logDir, logName, logSize)
	})

	return
}

// InitLoggerByConf 使用配置初始化Logger
func InitLoggerByConf(opt ILoggerOption) (err error) {
	if nil == opt {
		return InitLogger("", "", 0)
	}

	return InitLogger(opt.GetLogDir(), opt.GetLogName(), opt.GetLogSize())
}

// NewRecorder 初始化Recorder
func NewRecorder(id string) *Recorder {
	if "" == id {
		id = genRecorderId()
	}

	return &Recorder{id: id}
}

// Debug 直接输出 静态方法
func Debug(format string, v ...interface{}) {
	stdLogger.Debug(format, v...)
}

// Info 直接输出 静态方法
func Info(format string, v ...interface{}) {
	stdLogger.Info(format, v...)
}

// Warn 直接输出 静态方法
func Warn(format string, v ...interface{}) {
	stdLogger.Warn(format, v...)
}

// Error 直接输出 静态方法
func Error(format string, v ...interface{}) {
	stdLogger.Error(format, v...)
}

// Fatal 直接输出 静态方法
func Fatal(format string, v ...interface{}) {
	stdLogger.Fatal(format, v...)
}

// formatLog 格式化日志
func formatLog(time time.Time, level, msg string, skip int) string {
	_, file, line, _ := runtime.Caller(skip)
	timeStr := time.Format(defaultTimeFormat)
	return fmt.Sprintf(defaultLogFormat, timeStr, level, shortFileName(file), strconv.Itoa(line), msg)
}

// shortFileName 简化文件名
func shortFileName(file string) string {
	short := file
	for i := len(file) - 1; i > 0; i-- {
		if file[i] == '/' {
			short = file[i+1:]
			break
		}
	}
	return short
}

// makeDir 创建目录
func makeDir(path string) (err error) {
	if !isExist(path) {
		err = os.MkdirAll(path, 0666)
	}

	return
}

// isExist 判断目录是否存在
func isExist(path string) bool {
	if _, err := os.Stat(path); nil != err && false == os.IsExist(err) {
		return false
	}

	return true
}

// genRecorderId 生成Recorder ID
func genRecorderId() string {
	u := uuid.NewV4().String()
	t := time.Now().Unix()
	h := md5.New()
	h.Write([]byte(fmt.Sprintf("%s%v", u, t)))

	return hex.EncodeToString(h.Sum(nil))
}
